package com.seu.me.zookeeper.curator.barrier;

import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.barriers.DistributedDoubleBarrier;
import org.apache.curator.retry.ExponentialBackoffRetry;

import java.util.Random;

/**
 * DistributedDoubleBarrier 同时进入、同时离开
 * 双栏栅：DistributedDoubleBarrier，双栏栅允许客户端在计算的开始和结束时同步。
 * 当足够的进程加入到双栏栅时，进程开始计算，当计算完成时离开栏栅。
 * <p>
 * public DistributedDoubleBarrier(CuratorFramework client, String barrierPath, int memberQty)
 * memberQty是成元数量，当enter()方法被调用时，成员被阻塞，直到所有的成员都调用了enter()方法。
 * 当leave()方法被调用时，它也阻塞调用线程，直到所有的成员都调用了leave()方法。
 * <p>
 * 就像百米赛跑比赛，发令枪响，所有的运动员开始跑，等所有的运动员跑过终点线，比赛才结束。
 *
 * @author liangfeihu
 * @since 2017/12/5 21:13.
 */
public class CuratorBarrier1 {

    /**
     * zookeeper地址
     */
    static final String CONNECT_ADDR = "192.168.169.129:2181,192.168.169.130:2181,192.168.169.131:2181";
    /**
     * session超时时间 ms
     */
    static final int SESSION_OUTTIME = 5000;

    public static void main(String[] args) throws Exception {

        for (int i = 0; i < 5; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 10);
                        CuratorFramework cf = CuratorFrameworkFactory.builder()
                                .connectString(CONNECT_ADDR)
                                .retryPolicy(retryPolicy)
                                .build();
                        cf.start();

                        DistributedDoubleBarrier barrier = new DistributedDoubleBarrier(cf, "/super2", 5);
                        Thread.sleep(1000 * (new Random()).nextInt(3));
                        System.out.println(Thread.currentThread().getName() + "已经准备");
                        barrier.enter();
                        System.out.println("同时开始运行...");
                        Thread.sleep(1000 * (new Random()).nextInt(3));
                        System.out.println(Thread.currentThread().getName() + "运行完毕");
                        barrier.leave();
                        System.out.println("同时退出运行...");

                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }, "t" + i).start();
        }

    }
}
